/*
 * File:   dynarraytest.c
 * Author: ossi
 *
 * Created on 06-Nov-2011, 17:59:58
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <CUnit/Basic.h>
#include "dynarray.h"

/*
 * CUnit Test Suite
 */

int init_suite(void) {
    return 0;
}

int clean_suite(void) {
    return 0;
}

void testDa_append_in() {
    dynarray* array = da_new();
    for (int i = 0; i < 10; ++i) {
        unsigned int* p = malloc(sizeof (unsigned int));
        *p = i;
        CU_ASSERT(da_append(array, p));
    }

    for (unsigned int i = 0; i < 10; ++i) {
        CU_ASSERT(*((unsigned int*) da_get(array, i)) == i);
    }
    unsigned int* k = malloc(sizeof (unsigned int));
    *k = 4;

    CU_ASSERT(da_append_in(array, k, 6));
    CU_ASSERT(array->top == 11);

    for (unsigned int i = 0; i < 6; ++i) {
        CU_ASSERT(*((unsigned int*) da_get(array, i)) == i);
        free(da_get(array, i));
    }

    CU_ASSERT(*((unsigned int*) da_get(array, 6)) == 4);
    free(da_get(array, 6));

    for (unsigned int i = 7; i < 11; ++i) {
        CU_ASSERT(*((unsigned int*) da_get(array, i)) == i - 1);
        free(da_get(array, i));
    }
    da_free(array);
}

int cmp_int(void* a, void* b) {
    unsigned int k = *((unsigned int*) a);
    unsigned int l = *((unsigned int*) b);
    return k - l;
}

void testDa_append_inorder() {
    dynarray* array = da_new();
    for (int i = 0; i < 10; ++i) {
        if (i == 5) continue;
        unsigned int* p = malloc(sizeof (unsigned int));
        *p = i;
        CU_ASSERT(da_append(array, p));
    }
    CU_ASSERT(array->top == 9);

    unsigned int* k = malloc(sizeof (unsigned int));
    *k = 5;
    da_append_inorder(array, k, &cmp_int,true);
    CU_ASSERT(array->top == 10);

    for (unsigned int i = 0; i < 10; ++i) {
        CU_ASSERT(*((unsigned int*) da_get(array, i)) == i);
        free(da_get(array, i));
    }

    da_free(array);
}

void testDa_binsearch() {
    dynarray* array = da_new();
    for (int i = 0; i < 10; ++i) {
        unsigned int* p = malloc(sizeof (unsigned int));
        *p = i;
        CU_ASSERT(da_append(array, p));
    }
    unsigned int k = 5;
    CU_ASSERT(da_binsearch(array, &k, 0, array->top, cmp_int) == (int)k);
    k = 8;
    CU_ASSERT(da_binsearch(array, &k, 0, array->top, cmp_int) == (int)k);
    k = 2;
    CU_ASSERT(da_binsearch(array, &k, 0, array->top, cmp_int) == (int)k);
    k = -1;
    CU_ASSERT(da_binsearch(array, &k, 0, array->top, cmp_int) == (int)k);
    for (unsigned int i = 0; i < 10; ++i) {
        CU_ASSERT(*((unsigned int*) da_get(array, i)) == i);
        free(da_get(array, i));
    }
    da_free(array);
}

void testDa_remove() {
    dynarray* array = da_new();
    for (int i = 0; i < 10; ++i) {
        unsigned int* p = malloc(sizeof (unsigned int));
        *p = i;
        CU_ASSERT(da_append(array, p));
    }
    
     unsigned int* k = (unsigned int*)da_remove(array,2);
     CU_ASSERT(*k == 2);
     CU_ASSERT(array->top == 9);
     k = (unsigned int*)da_remove(array,2);
     CU_ASSERT(*k == 3);
     CU_ASSERT(array->top == 8);
     k = (unsigned int*)da_remove(array,2);
     CU_ASSERT(*k == 4);
     CU_ASSERT(array->top == 7);
      for (unsigned int i = 0; i < 7; ++i) {
          k = (unsigned int*)da_remove(array,0);
        free(k);
    } 
     CU_ASSERT(array->top == 0);
     da_free(array);
}

int main() {
    CU_pSuite pSuite = NULL;

    /* Initialize the CUnit test registry */
    if (CUE_SUCCESS != CU_initialize_registry())
        return CU_get_error();

    /* Add a suite to the registry */
    pSuite = CU_add_suite("dynarraytest", init_suite, clean_suite);
    if (NULL == pSuite) {
        CU_cleanup_registry();
        return CU_get_error();
    }

    /* Add the tests to the suite */
    if ((NULL == CU_add_test(pSuite, "testDa_append_in", testDa_append_in)) ||
            (NULL == CU_add_test(pSuite, "testDa_append_inorder", testDa_append_inorder)) ||
            (NULL == CU_add_test(pSuite, "testDa_binsearch", testDa_binsearch)) ||
            (NULL == CU_add_test(pSuite, "testDa_remove", testDa_remove))) {
        CU_cleanup_registry();
        return CU_get_error();
    }

    /* Run all tests using the CUnit Basic interface */
    printf("dynarraytest.c:");
    CU_basic_set_mode(CU_BRM_VERBOSE);
    CU_basic_run_tests();
    CU_cleanup_registry();
    return CU_get_error();
}
